/*

Miranda IM: the free IM client for Microsoft* Windows*

Copyright 2000-2007 Miranda ICQ/IM project, 
all portions of this codebase are copyrighted to the people 
listed in contributors.txt.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
aLONG with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

/**
 * System Includes:
 **/
#include "commonheaders.h"
#include "ctrl.h"
#include "pspAll.h"
#include "Reminder.h"


COLORREF clrBoth = -1;
COLORREF clrChanged = -1;
COLORREF clrCustom = -1;
COLORREF clrNormal = -1;
COLORREF clrMeta = -1;

/**
 * name:   Ctrl_InitTextColours()
 * desc:   load colours from database
 *
 * return:   nothing
 **/
VOID Ctrl_InitTextColours(VOID)
{
	if(clrBoth == -1) clrBoth = DBGetSettingDword(NULL, MODNAME, SET_PROPSHEET_CLRBOTH, RGB(0, 160, 10));
	if(clrChanged == -1) clrChanged = DBGetSettingDword(NULL, MODNAME, SET_PROPSHEET_CLRCHANGED, RGB(190, 0, 0));
	if(clrCustom == -1) clrCustom = DBGetSettingDword(NULL, MODNAME, SET_PROPSHEET_CLRCUSTOM, RGB(0, 10, 130));
	if(clrNormal == -1) clrNormal = DBGetSettingDword(NULL, MODNAME, SET_PROPSHEET_CLRNORMAL, RGB(90, 90, 90));
	if(clrMeta == -1) clrMeta = DBGetSettingDword(NULL, MODNAME, SET_PROPSHEET_CLRMETA, RGB(120, 40, 130));
}

/**
 * name:   Ctrl_SetTextColour()
 * desc:   is called if the phone number combobox is redrawn
 *
 * return:   Brush or FALSE
 **/
INT CALLBACK Ctrl_SetTextColour(HDC hdc, WORD wFlags)
{
	SetTextColor(hdc, 
		(wFlags & CTRLF_CHANGED) 
			? clrChanged : ((wFlags & CTRLF_HASCUSTOM) && (wFlags & (CTRLF_HASPROTO|CTRLF_HASMETA)))
				? clrBoth : (wFlags & CTRLF_HASMETA)
					? clrMeta : (wFlags & CTRLF_HASCUSTOM)
						? clrCustom	: clrNormal
		);
	return (BOOL)GetStockObject(WHITE_BRUSH);
}

INT CALLBACK Ctrl_SetTextColour(HWND hCtrl, HDC hdc)
{
	if(hCtrl && DBGetByte(SET_PROPSHEET_SHOWCOLOURS, 1)) {
		LPCTRL pCtrl = (LPCTRL)GetUserData(hCtrl);
		if(PtrIsValid(pCtrl))
			return Ctrl_SetTextColour(hdc, pCtrl->wFlags);
	}
	return FALSE;
}

/**
 * name:	DlgProc_pspGeneral
 * desc:	dialog procedure for the general contact information propertysheetpage
 * param:	hDlg	- handle to the dialog window
 *			uMsg	- the message to handle
 *			wParam	- parameter
 *			lParam	- parameter
 * return:	different values
 **/
INT CALLBACK DlgProc_pspGeneral(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg) {
		
		case WM_INITDIALOG:
		{
			HANDLE hContact = (HANDLE)lParam;

			Ctrl_InitTextColours();	
			SetTimer(hDlg, 1, 5000, NULL);

			SendDlgItemMessage(hDlg, EDIT_AGE, EM_LIMITTEXT, 3, 0);
			SendDlgItemMessage(hDlg, SPIN_AGE, UDM_SETRANGE32, 0, 200);

			if(!hContact) {
				LPECTRL peCtrl = (LPECTRL)malloc(sizeof(ECTRL));

				if(!peCtrl) break;
				peCtrl->nType = CTRL_EDIT;
				peCtrl->wFlags = NULL;
				peCtrl->valueType = DBVT_ASCIIZ;	
				SendDlgItemMessage(hDlg, ICO_PASSWORD, STM_SETIMAGE, IMAGE_ICON, (LPARAM)NIcoLib::GetIcon(ICO_COMMON_PASSWORD));
				SetDlgItemText(hDlg, EDIT_PASSWORD, _T("**************"));
				SetUserData(GetDlgItem(hDlg, EDIT_PASSWORD), peCtrl);
				SetDlgItemText(hDlg, TXT_PASSWORD, _T("Password:"));
				ShowWindow(GetDlgItem(hDlg, EDIT_DISPLAYNAME), SW_HIDE);
				ShowWindow(GetDlgItem(hDlg, EDIT_PASSWORD), SW_SHOW);
			}
			else
				SendDlgItemMessage(hDlg, ICO_PASSWORD, STM_SETIMAGE, IMAGE_ICON, (LPARAM)NIcoLib::GetIcon(ICO_COMMON_IM));

			TranslateDialogDefault(hDlg);
			return TRUE;
		}

		case WM_CTLCOLOREDIT:
			return Ctrl_SetTextColour((HWND)lParam, (HDC)wParam);

		case WM_CTLCOLORSTATIC:
			switch(GetWindowLong((HWND)lParam, GWL_ID)) {
				case EDIT_TITLE:
				case EDIT_FIRSTNAME:
				case EDIT_SECONDNAME:
				case EDIT_LASTNAME:
				case EDIT_PREFIX:
				case EDIT_NICK:
				case EDIT_DISPLAYNAME:
				case EDIT_AGE:
				case EDIT_MARITAL:
				case EDIT_PARTNER:
				case EDIT_TIMEZONE:
					return (BOOL)GetStockObject(WHITE_BRUSH);
			}
			return FALSE;

		case WM_NOTIFY:
			switch (((LPNMHDR)lParam)->idFrom) {
				case 0:
				{
					HANDLE hContact = (HANDLE)((LPPSHNOTIFY)lParam)->lParam;
					LPCSTR szBaseProto;
			
					switch (((LPNMHDR)lParam)->code) {
						case PSN_RESET:
						{
							LPCTRL pData;

							if(PtrIsValid(pData = (LPCTRL)GetUserData(GetDlgItem(hDlg, EDIT_TITLE)))) pData->wFlags &= ~CTRLF_CHANGED;
							if(PtrIsValid(pData = (LPCTRL)GetUserData(GetDlgItem(hDlg, EDIT_FIRSTNAME)))) pData->wFlags &= ~CTRLF_CHANGED;
							if(PtrIsValid(pData = (LPCTRL)GetUserData(GetDlgItem(hDlg, EDIT_SECONDNAME)))) pData->wFlags &= ~CTRLF_CHANGED;
							if(PtrIsValid(pData = (LPCTRL)GetUserData(GetDlgItem(hDlg, EDIT_LASTNAME)))) pData->wFlags &= ~CTRLF_CHANGED;
							if(PtrIsValid(pData = (LPCTRL)GetUserData(GetDlgItem(hDlg, EDIT_PREFIX)))) pData->wFlags &= ~CTRLF_CHANGED;
							if(PtrIsValid(pData = (LPCTRL)GetUserData(GetDlgItem(hDlg, EDIT_NICK)))) pData->wFlags &= ~CTRLF_CHANGED;
							if(PtrIsValid(pData = (LPCTRL)GetUserData(GetDlgItem(hDlg, EDIT_DISPLAYNAME)))) pData->wFlags &= ~CTRLF_CHANGED;
							break;
						}

						case PSN_INFOCHANGED:
						{
							BYTE bChanged = 0;
							LPIDSTRLIST pList;
							UINT nList;
		
							if(!PSGetBaseProto(hDlg, szBaseProto) || *szBaseProto == 0) break;

							// naming
							bChanged |= Edit_SetValue(hDlg, EDIT_TITLE, hContact, USERINFO, szBaseProto, SET_CONTACT_TITLE);
							bChanged |= Edit_SetValue(hDlg, EDIT_FIRSTNAME, hContact, USERINFO, szBaseProto, SET_CONTACT_FIRSTNAME);
							bChanged |= Edit_SetValue(hDlg, EDIT_SECONDNAME, hContact, USERINFO, szBaseProto, SET_CONTACT_SECONDNAME);
							bChanged |= Edit_SetValue(hDlg, EDIT_LASTNAME, hContact, USERINFO, szBaseProto, SET_CONTACT_LASTNAME);
							GetNamePrefixList((WPARAM)&nList, (LPARAM)&pList);
							bChanged |= ComboBox_SelectItem(hDlg, EDIT_PREFIX, pList, nList, hContact, USERINFO, szBaseProto, SET_CONTACT_PREFIX, 0);
							// im-naming
							bChanged |= Edit_SetValue(hDlg, EDIT_NICK, hContact, USERINFO, szBaseProto, SET_CONTACT_NICK);
							if(hContact) bChanged |= Edit_SetValue(hDlg, EDIT_DISPLAYNAME, hContact, "CList", NULL, SET_CONTACT_MYHANDLE);

							// gender
							{
								DBVARIANT dbv;
								WORD wFlags;

								if(wFlags = DBGetSettingCtrlUnicode(hContact, USERINFO, USERINFO, szBaseProto, SET_CONTACT_GENDER, &dbv)) {
									if(dbv.type == DBVT_BYTE) {
										CheckDlgButton(hDlg, RADIO_FEMALE, (dbv.bVal == 'F'));
										CheckDlgButton(hDlg, RADIO_MALE, (dbv.bVal == 'M'));

										if(!(wFlags & CTRLF_HASCUSTOM) && (wFlags & (CTRLF_HASPROTO|CTRLF_HASMETA)) && DBGetByte(SET_PROPSHEET_PCBIREADONLY, 0)) {
											EnableWindow(GetDlgItem(hDlg, RADIO_FEMALE), FALSE);
											EnableWindow(GetDlgItem(hDlg, RADIO_MALE), FALSE);
										}
									}
									else
										DBFreeVariant(&dbv);
								}
							}
							
							// read age an zodiac
							{
								MAnnivDate mtb;
								HWND hPs = GetParent(hDlg);
								DLGCOMMAND dCmd;

								dCmd.hInst = ghInst;
								dCmd.idDlg = IDD_CONTACT_ORIGIN;
								dCmd.idDlgItem = 0;
								dCmd.uMsg = PSPM_GETBIRTHDATE;
								dCmd.wParam = NULL;
								dCmd.lParam = (LPARAM)&mtb;

								if(
									SendMessage(hPs, PSM_DLGMESSAGE, NULL, (LPARAM)&dCmd) ||
									!mtb.DBGetBirthDate(hContact, szBaseProto)
								  )
								{
									DlgProc_pspGeneral(hDlg, PSPM_SETAGEANDZIDIAC, NULL, (LPARAM)&mtb);
									Edit_Init(hContact, GetDlgItem(hDlg, EDIT_AGE));
								}
								else
									bChanged |= Edit_SetValue(hDlg, EDIT_AGE, hContact, USERINFO, szBaseProto, SET_CONTACT_AGE);
							}

							// marital groupbox
							GetMaritalList((WPARAM)&nList, (LPARAM)&pList);
							bChanged |= ComboBox_SelectItem(hDlg, EDIT_MARITAL, pList, nList, hContact, USERINFO, szBaseProto, SET_CONTACT_MARITAL, 0);
							bChanged |= Edit_SetValue(hDlg, EDIT_PARTNER, hContact, USERINFO, szBaseProto, SET_CONTACT_PARTNER);

							// timezone
							GetTimezoneList((WPARAM)&nList, (LPARAM)&pList);
							bChanged |= ComboBox_SelectItem(hDlg, EDIT_TIMEZONE, pList, nList, hContact, USERINFO, szBaseProto, SET_CONTACT_TIMEZONE, pList[0].nID, TRUE);
							SendMessage(hDlg, WM_TIMER, 0, 0);

							SetWindowLongPtr(hDlg, DWL_MSGRESULT, bChanged ? PSP_CHANGED : 0);
							break;
						}

						case PSN_APPLY:
							if(!PSGetBaseProto(hDlg, szBaseProto) || *szBaseProto == 0) break;

							// naming
							Edit_WriteValue(hDlg, EDIT_TITLE, hContact, USERINFO, szBaseProto, SET_CONTACT_TITLE);
							Edit_WriteValue(hDlg, EDIT_FIRSTNAME, hContact, USERINFO, szBaseProto, SET_CONTACT_FIRSTNAME);
							Edit_WriteValue(hDlg, EDIT_SECONDNAME, hContact, USERINFO, szBaseProto, SET_CONTACT_SECONDNAME);
							Edit_WriteValue(hDlg, EDIT_LASTNAME, hContact, USERINFO, szBaseProto, SET_CONTACT_LASTNAME);
							ComboBox_WriteItem(hDlg, EDIT_PREFIX, hContact, USERINFO, szBaseProto, SET_CONTACT_PREFIX, DBVT_BYTE);

							// im-naming
							Edit_WriteValue(hDlg, EDIT_NICK, hContact, USERINFO, szBaseProto, SET_CONTACT_NICK);
							
							if(hContact) {
								Edit_WriteValue(hDlg, EDIT_DISPLAYNAME, hContact, "CList", NULL, SET_CONTACT_MYHANDLE);
								CallService(MS_CLIST_INVALIDATEDISPLAYNAME, (WPARAM)hContact, NULL);
							}
							// save password
							else {
								CHAR szPass[64];
								HWND hEdit = GetDlgItem(hDlg, EDIT_PASSWORD);
								LPECTRL	peCtrl = (LPECTRL)GetUserData(hEdit);

								if(PtrIsValid(peCtrl) && (peCtrl->wFlags & CTRLF_CHANGED) &&
									GetWindowTextA(hEdit, szPass, sizeof(szPass)) > 0) 
								{
									CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(szPass), (LPARAM)szPass);
									DBWriteContactSettingString(NULL, szBaseProto, SET_ME_PASSWORD, szPass);
									peCtrl->wFlags &= ~CTRLF_CHANGED;
								}
							}


							// gender
							{
								BYTE gender
									= SendDlgItemMessage(hDlg, RADIO_FEMALE, BM_GETCHECK, NULL, NULL)
									? 'F'
									: SendDlgItemMessage(hDlg, RADIO_MALE, BM_GETCHECK, NULL, NULL)
									? 'M'
									: 0;

								if(gender) DBWriteContactSettingByte(hContact, hContact ? USERINFO : szBaseProto, SET_CONTACT_GENDER, gender);
								else DBDeleteContactSetting(hContact, hContact ? USERINFO : szBaseProto, SET_CONTACT_GENDER);
							}
							Edit_WriteValue(hDlg, EDIT_AGE, hContact, USERINFO, szBaseProto, SET_CONTACT_AGE, DBVT_WORD);
							Edit_WriteValue(hDlg, EDIT_PARTNER, hContact, USERINFO, szBaseProto, SET_CONTACT_PARTNER);
							ComboBox_WriteItem(hDlg, EDIT_MARITAL, hContact, USERINFO, szBaseProto, SET_CONTACT_MARITAL, DBVT_ASCIIZ);
							ComboBox_WriteItem(hDlg, EDIT_TIMEZONE, hContact, USERINFO, szBaseProto, SET_CONTACT_TIMEZONE, DBVT_BYTE, TRUE);
							break;

						case PSN_ICONCHANGED:
						{
							const NIcoLib::ICONCTRL idIcon[] = {
								{ ICO_COMMON_FEMALE,	STM_SETIMAGE,	ICO_FEMALE },
								{ ICO_COMMON_MALE,		STM_SETIMAGE,	ICO_MALE },
								{ ICO_COMMON_MARITAL,	STM_SETIMAGE,	ICO_MARITAL },
								{ ICO_COMMON_CLOCK,		STM_SETIMAGE,	ICO_CLOCK },
							};
							NIcoLib::SetCtrlIcons(hDlg, idIcon, SIZEOF(idIcon));
							break;
						}
					}
					break;
				}
			}
			break;

		case WM_COMMAND:
		{
			HANDLE hContact;
			LPCSTR szBaseProto;

			switch(LOWORD(wParam)) {
				case EDIT_TIMEZONE:
				case EDIT_PREFIX:
				case EDIT_MARITAL:
					switch(HIWORD(wParam)) {
						case CBN_DROPDOWN:
						case CBN_SETFOCUS:
							ComboBox_DropDown((HWND)lParam);
							break;
						case CBN_SELCHANGE:
							if(!PspIsLocked(hDlg)) {
								ComboBox_SelChanged(hDlg, (HWND)lParam);
								if(LOWORD(wParam) == EDIT_TIMEZONE)
									SendMessage(hDlg, WM_TIMER, 0, 0);
							}
							break;
					}
					break;
				case EDIT_TITLE:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_TITLE);
					break;
				case EDIT_FIRSTNAME:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_FIRSTNAME);
					break;
				case EDIT_SECONDNAME:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_SECONDNAME);
					break;
				case EDIT_LASTNAME:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_LASTNAME);
					break;
				case EDIT_NICK:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_NICK);
					break;
				case EDIT_DISPLAYNAME:
					if(HIWORD(wParam) == EN_UPDATE && PSGetContact(hDlg, hContact) && hContact)
						Edit_Changed(hDlg, LOWORD(wParam), "CList", SET_CONTACT_MYHANDLE);
					break;
				case RADIO_FEMALE:
					PSGetContact(hDlg, hContact);
					if(!PspIsLocked(hDlg) && HIWORD(wParam) == BN_CLICKED && PSGetBaseProto(hDlg, szBaseProto)) {
						DBVARIANT dbv;

						if(!DBGetSettingCtrlUnicode(hContact, USERINFO, USERINFO, szBaseProto, SET_CONTACT_GENDER, &dbv) ||
							dbv.type != DBVT_BYTE ||
							!dbv.bVal ||
							(dbv.bVal == 'M' && SendMessage((HWND)lParam, BM_GETCHECK, NULL, NULL))
						  )
						{
							SendMessage(GetParent(hDlg), PSM_CHANGED, NULL, NULL);
						}
					}
					break;

				case RADIO_MALE:
					PSGetContact(hDlg, hContact);
					if(!PspIsLocked(hDlg) && HIWORD(wParam) == BN_CLICKED && PSGetBaseProto(hDlg, szBaseProto)) {
						DBVARIANT dbv;
						if(!DBGetSettingCtrlUnicode(hContact, USERINFO, USERINFO, szBaseProto, SET_CONTACT_GENDER, &dbv) ||
							dbv.type != DBVT_BYTE ||
							!dbv.bVal ||
							(dbv.bVal == 'F' && SendMessage((HWND)lParam, BM_GETCHECK, NULL, NULL))
						  )
						{
							SendMessage(GetParent(hDlg), PSM_CHANGED, NULL, NULL);
						}
					}
					break;
				case EDIT_PASSWORD:
					if(!PspIsLocked(hDlg)) {
						TCHAR szPass[64];
						HWND hEdit = (HWND)lParam;
						LPECTRL	peCtrl = (LPECTRL)GetUserData(hEdit);

						if(PtrIsValid(peCtrl) && !(peCtrl->wFlags & CTRLF_CHANGED)) {
							switch(HIWORD(wParam)) {
								case EN_SETFOCUS:
									SetWindowText(hEdit, _T(""));
									break;
								case EN_KILLFOCUS:
									SetWindowText(hEdit, _T("**************"));
									break;
								case EN_UPDATE:
									if(GetWindowText(hEdit, szPass, sizeof(szPass)) > 0 && _tcscmp(szPass, _T("**************"))) {
										SendMessage(GetParent(hDlg), PSM_CHANGED, NULL, NULL);
										peCtrl->wFlags |= CTRLF_CHANGED;
									}
									break;
							}
						}
					}
					break;
				case EDIT_AGE:
					if(!PspIsLocked(hDlg) && HIWORD(wParam) == EN_UPDATE)
						if(Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_AGE) == TRUE) {
							// TODO: change birthday date
						}
					break;
				case EDIT_PARTNER:
					if(!PspIsLocked(hDlg) && HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_PARTNER);
					break;
			}
			break;
		}

		case WM_TIMER:
		{
			HWND hTimeComboBox = GetDlgItem(hDlg, EDIT_TIMEZONE);
			INT  nCurSel = SendMessage(hTimeComboBox, CB_GETCURSEL, 0, 0);
			LPIDSTRLIST pListItem;

			if(nCurSel != CB_ERR && (pListItem = (LPIDSTRLIST)SendMessage(hTimeComboBox, CB_GETITEMDATA, nCurSel, 0))) {

				if(pListItem->nID <= 24 && pListItem->nID >= - 24) {
					MTime now;
					TCHAR szTime[32];

					now.GetTimeUTC();
					now.UTCToTzSpecificLocal(pListItem->nID);
					now.TimeFormat(szTime, SIZEOF(szTime));
					SetDlgItemText(hDlg, TXT_TIME, szTime);
				}
				else
					SetDlgItemText(hDlg, TXT_TIME, _T("--:--"));
			}
			break;
		}

		case PSPM_SETAGEANDZIDIAC:
		{
			MAnnivDate *mt = (MAnnivDate*)lParam;
			INT age;
			MZodiac zod;

			if(!PtrIsValid(mt)) break;

			zod = mt->Zodiac();
			if(zod.pszName != NULL) {
				ShowWindow(GetDlgItem(hDlg, TEXT_ZODIAC), SW_SHOW);
				SetDlgItemText(hDlg, TEXT_ZODIAC, TranslateTS(zod.pszName));
				SendDlgItemMessage(hDlg, IDC_ZODIAC, STM_SETIMAGE, IMAGE_ICON, (LPARAM)zod.hIcon);
			}
			else
				ShowWindow(GetDlgItem(hDlg, TEXT_ZODIAC), SW_HIDE);
			
			if((age = mt->Age()) > 0)
				SetDlgItemInt(hDlg, EDIT_AGE, age , FALSE);
			break;
		}

		case WM_DESTROY:
			KillTimer(hDlg, 1);
			Edit_Destroy(hDlg, EDIT_NICK);
			Edit_Destroy(hDlg, EDIT_TITLE);
			Edit_Destroy(hDlg, EDIT_FIRSTNAME);
			Edit_Destroy(hDlg, EDIT_SECONDNAME);
			Edit_Destroy(hDlg, EDIT_LASTNAME);
			Edit_Destroy(hDlg, EDIT_DISPLAYNAME);
			Edit_Destroy(hDlg, EDIT_PASSWORD);
			Edit_Destroy(hDlg, EDIT_AGE);
			Edit_Destroy(hDlg, EDIT_PARTNER);
			ComboBox_Destroy(hDlg, EDIT_MARITAL);
			ComboBox_Destroy(hDlg, EDIT_PREFIX);
			ComboBox_Destroy(hDlg, EDIT_TIMEZONE);
			break;
	}
	return FALSE;
}

/**
 * name:	DlgProc_pspContactHome
 * desc:	dialog procedure for the general contact information propertysheetpage
 * param:	hDlg	- handle to the dialog window
 *			uMsg	- the message to handle
 *			wParam	- parameter
 *			lParam	- parameter
 * return:	different values
 **/
INT CALLBACK DlgProc_pspContactHome(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg) {
		
		case WM_INITDIALOG:
		{
			TCHAR szAddr[MAX_PATH];
			HANDLE hContact = (HANDLE)lParam;

			TranslateDialogDefault(hDlg);
			Ctrl_InitTextColours();	
			mir_sntprintf(szAddr, MAX_PATH, _T("%s (%s)"), TranslateT("Address"), TranslateT("Home"));
			SetDlgItemText(hDlg, STATIC_ADDRESS, szAddr);
			SendDlgItemMessage(hDlg, BTN_GOTO, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Open in Browser"), MBF_TCHAR);
			return TRUE;
		}
		case WM_CTLCOLOREDIT:
			return Ctrl_SetTextColour((HWND)lParam, (HDC)wParam);

		case WM_CTLCOLORSTATIC:
			switch(GetWindowLong((HWND)lParam, GWL_ID)) {
				case EDIT_STREET:
				case EDIT_CITY:
				case EDIT_ZIP:
				case EDIT_STATE:
				case EDIT_COUNTRY:
				case EDIT_HOMEPAGE:
					return (BOOL)GetStockObject(WHITE_BRUSH);
			}
			return FALSE;

		case WM_NOTIFY:
			switch (((LPNMHDR)lParam)->idFrom) {
				case 0:
				{
					HANDLE hContact = (HANDLE)((LPPSHNOTIFY)lParam)->lParam;
					LPCSTR szBaseProto;
					HWND hCtrl;
			
					switch (((LPNMHDR)lParam)->code) {
						case PSN_INFOCHANGED:
						{
							BYTE bChanged = 0;
							LPIDSTRLIST pList;
							UINT nList;

							if(!PSGetBaseProto(hDlg, szBaseProto) || *szBaseProto == 0) break;

							// address
							bChanged |= Edit_SetValue(hDlg, EDIT_STREET, hContact, USERINFO, szBaseProto, SET_CONTACT_STREET);
							bChanged |= Edit_SetValue(hDlg, EDIT_CITY, hContact, USERINFO, szBaseProto, SET_CONTACT_CITY);
							bChanged |= Edit_SetValue(hDlg, EDIT_ZIP, hContact, USERINFO, szBaseProto, SET_CONTACT_ZIP);
							bChanged |= Edit_SetValue(hDlg, EDIT_STATE, hContact, USERINFO, szBaseProto, SET_CONTACT_STATE);
							GetCountryList((WPARAM)&nList, (LPARAM)&pList);
							bChanged |= ComboBox_SelectItem(hDlg, EDIT_COUNTRY, pList, nList, hContact, USERINFO, szBaseProto, SET_CONTACT_COUNTRY, 0);
							ComboBox_CountrySelChanged(hDlg, GetDlgItem(hDlg, EDIT_COUNTRY), GetDlgItem(hDlg, ICO_COUNTRY));
							// homepage
							bChanged |= Edit_SetValue(hDlg, EDIT_HOMEPAGE, hContact, USERINFO, szBaseProto, SET_CONTACT_HOMEPAGE);

							// phone numbers
							hCtrl = GetDlgItem(hDlg, EDIT_PHONE);
							bChanged |= CbEx_AddItemFromDB(hCtrl, ICO_BTN_PHONE, TranslateT(SET_CONTACT_PHONE), hContact, USERINFO, szBaseProto, SET_CONTACT_PHONE);
							bChanged |= CbEx_AddItemFromDB(hCtrl, ICO_BTN_FAX, TranslateT(SET_CONTACT_FAX), hContact, USERINFO, szBaseProto, SET_CONTACT_FAX);
							bChanged |= CbEx_AddItemFromDB(hCtrl, ICO_BTN_CELLULAR, TranslateT(SET_CONTACT_CELLULAR), hContact, USERINFO, szBaseProto, SET_CONTACT_CELLULAR);
							bChanged |= CbEx_AddMyItemsFromDB(hCtrl, ICO_BTN_CUSTOMPHONE, 0, hContact, USERINFO, szBaseProto, SET_CONTACT_MYPHONE_CAT, SET_CONTACT_MYPHONE_VAL);
							SendMessage(hCtrl, CBEXM_SETCURSEL, (WPARAM)-1, TRUE);

							// emails
							hCtrl = GetDlgItem(hDlg, EDIT_EMAIL);
							bChanged |= CbEx_AddItemFromDB(hCtrl, ICO_BTN_EMAIL, TranslateT("Primary e-mail"), hContact, USERINFO, szBaseProto, SET_CONTACT_EMAIL);
							bChanged |= CbEx_AddItemFromDB(hCtrl, ICO_BTN_EMAIL, TranslateT("Secondary e-mail"), hContact, USERINFO, szBaseProto, SET_CONTACT_EMAIL0);
							bChanged |= CbEx_AddItemFromDB(hCtrl, ICO_BTN_EMAIL, TranslateT("Tertiary e-mail"), hContact, USERINFO, szBaseProto, SET_CONTACT_EMAIL1);
							bChanged |= CbEx_AddMyItemsFromDB(hCtrl, ICO_BTN_EMAIL, 0, hContact, USERINFO, szBaseProto, SET_CONTACT_MYEMAIL_CAT, SET_CONTACT_MYEMAIL_VAL);
							SendMessage(hCtrl, CBEXM_SETCURSEL, (WPARAM)-1, TRUE);
							SetWindowLongPtr(hDlg, DWL_MSGRESULT, bChanged ? PSP_CHANGED : 0);
							break;
						}
						case PSN_APPLY:
							if(!PSGetBaseProto(hDlg, szBaseProto) || *szBaseProto == 0) break;
							// address
							Edit_WriteValue(hDlg, EDIT_STREET, hContact, USERINFO, szBaseProto, SET_CONTACT_STREET);
							Edit_WriteValue(hDlg, EDIT_CITY, hContact, USERINFO, szBaseProto, SET_CONTACT_CITY);
							Edit_WriteValue(hDlg, EDIT_ZIP, hContact, USERINFO, szBaseProto, SET_CONTACT_ZIP);
							Edit_WriteValue(hDlg, EDIT_STATE, hContact, USERINFO, szBaseProto, SET_CONTACT_STATE);
							ComboBox_WriteItem(hDlg, EDIT_COUNTRY, hContact, USERINFO, szBaseProto, SET_CONTACT_COUNTRY, DBVT_WORD);
							Edit_WriteValue(hDlg, EDIT_HOMEPAGE, hContact, USERINFO, szBaseProto, SET_CONTACT_HOMEPAGE);
							
							hCtrl = GetDlgItem(hDlg, EDIT_PHONE);
							CbEx_WriteItemToDB(hCtrl, hContact, USERINFO, szBaseProto, SET_CONTACT_PHONE);
							CbEx_WriteItemToDB(hCtrl, hContact, USERINFO, szBaseProto, SET_CONTACT_FAX);
							CbEx_WriteItemToDB(hCtrl, hContact, USERINFO, szBaseProto, SET_CONTACT_CELLULAR);
							CbEx_WriteMyItemsToDB(hCtrl, 3, hContact, USERINFO, szBaseProto, SET_CONTACT_MYPHONE_CAT, SET_CONTACT_MYPHONE_VAL);
							SendMessage(hCtrl, CBEXM_RESETCHANGED, NULL, NULL);

							hCtrl = GetDlgItem(hDlg, EDIT_EMAIL);
							CbEx_WriteItemToDB(hCtrl, hContact, USERINFO, szBaseProto, SET_CONTACT_EMAIL);
							CbEx_WriteItemToDB(hCtrl, hContact, USERINFO, szBaseProto, SET_CONTACT_EMAIL0);
							CbEx_WriteItemToDB(hCtrl, hContact, USERINFO, szBaseProto, SET_CONTACT_EMAIL1);
							CbEx_WriteMyItemsToDB(hCtrl, 3, hContact, USERINFO, szBaseProto, SET_CONTACT_MYEMAIL_CAT, SET_CONTACT_MYEMAIL_VAL);
							SendMessage(hCtrl, CBEXM_RESETCHANGED, NULL, NULL);
							break;
						case PSN_ICONCHANGED:
						{
							HICON hIcon;

							hIcon = NIcoLib::GetIcon(ICO_BTN_GOTO);
							if(hIcon == NIcoLib::hEmptyIcon) hIcon = NULL;
							SendDlgItemMessage(hDlg, BTN_GOTO, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
							SetDlgItemText(hDlg, BTN_GOTO, hIcon ? _T("") : _T("->"));

							hIcon = NIcoLib::GetIcon(ICO_COMMON_ADDRESS);
							if(hIcon == NIcoLib::hEmptyIcon) hIcon = NULL;
							SendDlgItemMessage(hDlg, ICO_ADDRESS, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
							ShowWindow(GetDlgItem(hDlg, ICO_ADDRESS), hIcon ? SW_SHOW : SW_HIDE);

							SendDlgItemMessage(hDlg, EDIT_PHONE, WM_SETICON, NULL, NULL);
							SendDlgItemMessage(hDlg, EDIT_EMAIL, WM_SETICON, NULL, NULL);
							break;
						}
					}
					break;
				}
			}
			break;

		case WM_COMMAND:
		{
			switch(LOWORD(wParam)) {
				case EDIT_COUNTRY:
					switch(HIWORD(wParam)) {
						case CBN_DROPDOWN:
						case CBN_SETFOCUS:
							ComboBox_DropDown((HWND)lParam);
							break;
						case CBN_SELCHANGE:
							ComboBox_CountrySelChanged(hDlg, (HWND)lParam, GetDlgItem(hDlg, ICO_COUNTRY));
							break;
					}
					break;
				case EDIT_STREET:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_STREET);
					break;
				case EDIT_ZIP:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_ZIP);
					break;
				case EDIT_CITY:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_CITY);
					break;
				case EDIT_STATE:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_STATE);
					break;
				case EDIT_HOMEPAGE:
					if(HIWORD(wParam) == EN_UPDATE) {
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_HOMEPAGE);
						EnableWindow(GetDlgItem(hDlg, BTN_GOTO), GetWindowTextLength((HWND)lParam) > 0);
					}
					break;
				case BTN_GOTO:
					Edit_OpenUrl(hDlg, EDIT_HOMEPAGE);
					break;
			}
			break;
		}

		case WM_DESTROY:
			Edit_Destroy(hDlg, EDIT_STREET);
			Edit_Destroy(hDlg, EDIT_ZIP);
			Edit_Destroy(hDlg, EDIT_CITY);
			Edit_Destroy(hDlg, EDIT_STATE);
			Edit_Destroy(hDlg, EDIT_HOMEPAGE);
			ComboBox_Destroy(hDlg, EDIT_COUNTRY);
			break;
	}
	return FALSE;
}


/**
 * name:	DlgProc_pspCompany
 * desc:	dialog procedure for the company contact information propertysheetpage
 * param:	hDlg	- handle to the dialog window
 *			uMsg	- the message to handle
 *			wParam	- parameter
 *			lParam	- parameter
 * return:	different values
 **/
INT CALLBACK DlgProc_pspCompany(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg) {
	      
		case WM_INITDIALOG:
			TranslateDialogDefault(hDlg);
			Ctrl_InitTextColours();	
			return TRUE;

		case WM_CTLCOLOREDIT:
			return Ctrl_SetTextColour((HWND)lParam, (HDC)wParam);
		case WM_CTLCOLORSTATIC:
			switch(GetWindowLong((HWND)lParam, GWL_ID)) {
				case EDIT_COMPANY:
				case EDIT_DEPARTMENT:
				case EDIT_OFFICE:
				case EDIT_POSITION:
				case EDIT_SUPERIOR:
				case EDIT_ASSISTENT:
				case EDIT_OCCUPATION:
				case EDIT_LANG1:
				case EDIT_LANG2:
				case EDIT_LANG3:
					return (BOOL)GetStockObject(WHITE_BRUSH);
			}
			return FALSE;


		case WM_NOTIFY:
			switch (((LPNMHDR)lParam)->idFrom) {
				case 0:
				{
					HANDLE hContact = (HANDLE)((LPPSHNOTIFY)lParam)->lParam;
					LPCSTR szBaseProto;

					switch (((LPNMHDR)lParam)->code) {
						// some account data may have changed so reread database
						case PSN_INFOCHANGED:
						{
							BYTE bChanged = 0;
							UINT nList;
							LPIDSTRLIST pList;

							if(!PSGetBaseProto(hDlg, szBaseProto) || *szBaseProto == 0) break;

							bChanged |= Edit_SetValue(hDlg, EDIT_COMPANY, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY);
							bChanged |= Edit_SetValue(hDlg, EDIT_DEPARTMENT, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_DEPARTMENT);
							bChanged |= Edit_SetValue(hDlg, EDIT_OFFICE, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_OFFICE);
							bChanged |= Edit_SetValue(hDlg, EDIT_POSITION, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_POSITION);
							bChanged |= Edit_SetValue(hDlg, EDIT_SUPERIOR, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_SUPERIOR);
							bChanged |= Edit_SetValue(hDlg, EDIT_ASSISTENT, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_ASSISTENT);
							GetOccupationList((WPARAM)&nList, (LPARAM)&pList);
							bChanged |= ComboBox_SelectItem(hDlg, EDIT_OCCUPATION, pList, nList, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_OCCUPATION, 0);
							// language groupbox
							GetLanguageList((WPARAM)&nList, (LPARAM)&pList);
							bChanged |= ComboBox_SelectItem(hDlg, EDIT_LANG1, pList, nList, hContact, USERINFO, szBaseProto, SET_CONTACT_LANG1, 0);
							bChanged |= ComboBox_SelectItem(hDlg, EDIT_LANG2, pList, nList, hContact, USERINFO, szBaseProto, SET_CONTACT_LANG2, 0);
							bChanged |= ComboBox_SelectItem(hDlg, EDIT_LANG3, pList, nList, hContact, USERINFO, szBaseProto, SET_CONTACT_LANG3, 0);

							SetWindowLongPtr(hDlg, DWL_MSGRESULT, bChanged ? PSP_CHANGED : 0);
							break;
						}
						// user selected to apply settings to the database
						case PSN_APPLY:
							if(!PSGetBaseProto(hDlg, szBaseProto) || *szBaseProto == 0) break;
							Edit_WriteValue(hDlg, EDIT_COMPANY, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY);
							Edit_WriteValue(hDlg, EDIT_DEPARTMENT, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_DEPARTMENT);
							Edit_WriteValue(hDlg, EDIT_OFFICE, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_OFFICE);
							Edit_WriteValue(hDlg, EDIT_POSITION, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_POSITION);
							Edit_WriteValue(hDlg, EDIT_SUPERIOR, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_SUPERIOR);
							Edit_WriteValue(hDlg, EDIT_ASSISTENT, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_ASSISTENT);
							ComboBox_WriteItem(hDlg, EDIT_OCCUPATION, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_OCCUPATION, DBVT_WORD);
							ComboBox_WriteItem(hDlg, EDIT_LANG1, hContact, USERINFO, szBaseProto, SET_CONTACT_LANG1, DBVT_ASCIIZ);
							ComboBox_WriteItem(hDlg, EDIT_LANG2, hContact, USERINFO, szBaseProto, SET_CONTACT_LANG2, DBVT_ASCIIZ);
							ComboBox_WriteItem(hDlg, EDIT_LANG3, hContact, USERINFO, szBaseProto, SET_CONTACT_LANG3, DBVT_ASCIIZ);
							break;
					}
					break;
				}
			}
			break;

		case WM_COMMAND:
		{
			switch(LOWORD(wParam)) {
				case EDIT_OCCUPATION:
				case EDIT_LANG1:
				case EDIT_LANG2:
				case EDIT_LANG3:
					switch(HIWORD(wParam)) {
						case CBN_SETFOCUS:
						case CBN_DROPDOWN:
							ComboBox_DropDown((HWND)lParam);
							break;
						case CBN_SELCHANGE:
							if(!PspIsLocked(hDlg)) 
								ComboBox_SelChanged(hDlg, (HWND)lParam);
							break;
					}
					break;

				/*
				Edit control's content may have changed. Check this.
				*/
				case EDIT_COMPANY:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_COMPANY);
					break;
				case EDIT_DEPARTMENT:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_COMPANY_DEPARTMENT);
					break;
				case EDIT_OFFICE:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_COMPANY_OFFICE);
					break;
				case EDIT_POSITION:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_COMPANY_POSITION);
					break;
				case EDIT_SUPERIOR:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_COMPANY_SUPERIOR);
					break;
				case EDIT_ASSISTENT:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_COMPANY_ASSISTENT);
					break;
			}
			break;
		}
		case WM_DESTROY:
			Edit_Destroy(hDlg, EDIT_SUPERIOR);
			Edit_Destroy(hDlg, EDIT_ASSISTENT);
			Edit_Destroy(hDlg, EDIT_COMPANY);
			Edit_Destroy(hDlg, EDIT_DEPARTMENT);
			Edit_Destroy(hDlg, EDIT_OFFICE);
			Edit_Destroy(hDlg, EDIT_POSITION);
			ComboBox_Destroy(hDlg, EDIT_OCCUPATION);
			ComboBox_Destroy(hDlg, EDIT_LANG1);
			ComboBox_Destroy(hDlg, EDIT_LANG2);
			ComboBox_Destroy(hDlg, EDIT_LANG3);
			break;
	}
	return FALSE;
}      

/**
 * name:	DlgProc_pspContactWork
 * desc:	dialog procedure for the general contact information propertysheetpage
 * param:	hDlg	- handle to the dialog window
 *			uMsg	- the message to handle
 *			wParam	- parameter
 *			lParam	- parameter
 * return:	different values
 **/
INT CALLBACK DlgProc_pspContactWork(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg) {
		
		case WM_INITDIALOG:
		{
			TCHAR szAddr[MAX_PATH];
			HANDLE hContact = (HANDLE)lParam;

			TranslateDialogDefault(hDlg);
			Ctrl_InitTextColours();
			
			mir_sntprintf(szAddr, MAX_PATH, _T("%s (%s)"), TranslateT("Address"), TranslateT("Company"));
			SetDlgItemText(hDlg, STATIC_ADDRESS, szAddr);
			SendDlgItemMessage(hDlg, BTN_GOTO, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Open in Browser"), MBF_TCHAR);
			return TRUE;
		}
		case WM_CTLCOLOREDIT:
			return Ctrl_SetTextColour((HWND)lParam, (HDC)wParam);
		
		case WM_CTLCOLORSTATIC:
			switch(GetWindowLong((HWND)lParam, GWL_ID)) {
				case EDIT_STREET:
				case EDIT_CITY:
				case EDIT_ZIP:
				case EDIT_STATE:
				case EDIT_COUNTRY:
				case EDIT_PHONE:
				case EDIT_HOMEPAGE:
					return (BOOL)GetStockObject(WHITE_BRUSH);
			}
			return FALSE;

		case WM_NOTIFY:
			switch (((LPNMHDR)lParam)->idFrom) {
				case 0:
				{
					HANDLE hContact = (HANDLE)((LPPSHNOTIFY)lParam)->lParam;
					LPCSTR szBaseProto;
					HWND hCtrl;
			
					switch (((LPNMHDR)lParam)->code) {
						case PSN_INFOCHANGED:
						{
							BYTE bChanged = 0;
							LPIDSTRLIST pList;
							UINT nList;

							if(!PSGetBaseProto(hDlg, szBaseProto) || *szBaseProto == 0) break;

							// address
							bChanged |= Edit_SetValue(hDlg, EDIT_STREET, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_STREET);
							bChanged |= Edit_SetValue(hDlg, EDIT_CITY, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_CITY);
							bChanged |= Edit_SetValue(hDlg, EDIT_ZIP, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_ZIP);
							bChanged |= Edit_SetValue(hDlg, EDIT_STATE, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_STATE);
							GetCountryList((WPARAM)&nList, (LPARAM)&pList);
							bChanged |= ComboBox_SelectItem(hDlg, EDIT_COUNTRY, pList, nList, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_COUNTRY, 0);
							ComboBox_CountrySelChanged(hDlg, GetDlgItem(hDlg, EDIT_COUNTRY), GetDlgItem(hDlg, ICO_COUNTRY));

							// homepage
							bChanged |= Edit_SetValue(hDlg, EDIT_HOMEPAGE, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_HOMEPAGE);

							// phone numbers
							hCtrl = GetDlgItem(hDlg, EDIT_PHONE);
							bChanged |= CbEx_AddItemFromDB(hCtrl, ICO_BTN_PHONE, TranslateT(SET_CONTACT_PHONE), hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_PHONE);
							bChanged |= CbEx_AddItemFromDB(hCtrl, ICO_BTN_FAX, TranslateT(SET_CONTACT_FAX), hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_FAX);
							bChanged |= CbEx_AddItemFromDB(hCtrl, ICO_BTN_CELLULAR, TranslateT(SET_CONTACT_CELLULAR), hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_CELLULAR);
							bChanged |= CbEx_AddMyItemsFromDB(hCtrl, ICO_BTN_CUSTOMPHONE, 0, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_MYPHONE_CAT, SET_CONTACT_COMPANY_MYPHONE_VAL);
							SendMessage(hCtrl, CBEXM_SETCURSEL, (WPARAM)-1, TRUE);
								
							// emails
							hCtrl = GetDlgItem(hDlg, EDIT_EMAIL);
							bChanged |= CbEx_AddItemFromDB(hCtrl, ICO_BTN_EMAIL, TranslateT("Primary e-mail"), hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_EMAIL);
							bChanged |= CbEx_AddItemFromDB(hCtrl, ICO_BTN_EMAIL, TranslateT("Secondary e-mail"), hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_EMAIL0);
							bChanged |= CbEx_AddItemFromDB(hCtrl, ICO_BTN_EMAIL, TranslateT("Tertiary e-mail"), hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_EMAIL1);
							bChanged |= CbEx_AddMyItemsFromDB(hCtrl, ICO_BTN_EMAIL, 0, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_MYEMAIL_CAT, SET_CONTACT_COMPANY_MYEMAIL_VAL);
							SendMessage(hCtrl, CBEXM_SETCURSEL, (WPARAM)-1, TRUE);
							SetWindowLongPtr(hDlg, DWL_MSGRESULT, bChanged ? PSP_CHANGED : 0);
							break;
						}
						case PSN_APPLY:
							if(!PSGetBaseProto(hDlg, szBaseProto) || *szBaseProto == 0) break;
							// address
							SetFocus(hDlg);
							Edit_WriteValue(hDlg, EDIT_STREET, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_STREET);
							Edit_WriteValue(hDlg, EDIT_CITY, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_CITY);
							Edit_WriteValue(hDlg, EDIT_ZIP, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_ZIP);
							Edit_WriteValue(hDlg, EDIT_STATE, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_STATE);
							ComboBox_WriteItem(hDlg, EDIT_COUNTRY, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_COUNTRY, DBVT_WORD);
							Edit_WriteValue(hDlg, EDIT_HOMEPAGE, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_HOMEPAGE);

							hCtrl = GetDlgItem(hDlg, EDIT_PHONE);
							CbEx_WriteItemToDB(hCtrl, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_PHONE);
							CbEx_WriteItemToDB(hCtrl, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_FAX);
							CbEx_WriteItemToDB(hCtrl, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_CELLULAR);
							CbEx_WriteMyItemsToDB(hCtrl, 3, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_MYPHONE_CAT, SET_CONTACT_COMPANY_MYPHONE_VAL);
							SendMessage(hCtrl, CBEXM_RESETCHANGED, NULL, NULL);

							hCtrl = GetDlgItem(hDlg, EDIT_EMAIL);
							CbEx_WriteItemToDB(hCtrl, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_EMAIL);
							CbEx_WriteItemToDB(hCtrl, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_EMAIL0);
							CbEx_WriteItemToDB(hCtrl, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_EMAIL1);
							CbEx_WriteMyItemsToDB(hCtrl, 3, hContact, USERINFO, szBaseProto, SET_CONTACT_COMPANY_MYEMAIL_CAT, SET_CONTACT_COMPANY_MYEMAIL_VAL);
							SendMessage(hCtrl, CBEXM_RESETCHANGED, NULL, NULL);
							break;

						case PSN_ICONCHANGED:
						{
							HICON hIcon;

							hIcon = NIcoLib::GetIcon(ICO_BTN_GOTO);
							if(hIcon == NIcoLib::hEmptyIcon) hIcon = NULL;
							SendDlgItemMessage(hDlg, BTN_GOTO, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
							SetDlgItemText(hDlg, BTN_GOTO, hIcon ? _T("") : _T("->"));

							hIcon = NIcoLib::GetIcon(ICO_COMMON_ADDRESS);
							if(hIcon == NIcoLib::hEmptyIcon) hIcon = NULL;
							SendDlgItemMessage(hDlg, ICO_ADDRESS, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
							ShowWindow(GetDlgItem(hDlg, ICO_ADDRESS), hIcon ? SW_SHOW : SW_HIDE);

							SendDlgItemMessage(hDlg, EDIT_PHONE, WM_SETICON, NULL, NULL);
							SendDlgItemMessage(hDlg, EDIT_EMAIL, WM_SETICON, NULL, NULL);
							break;
						}
					}
					break;
				}
			}
			break;

		case WM_COMMAND:
		{
			switch(LOWORD(wParam)) {
				case EDIT_COUNTRY:
					switch(HIWORD(wParam)) {
						case CBN_DROPDOWN:
						case CBN_SETFOCUS:
							ComboBox_DropDown((HWND)lParam);
							break;
						case CBN_SELCHANGE:
							ComboBox_CountrySelChanged(hDlg, (HWND)lParam, GetDlgItem(hDlg, ICO_COUNTRY));
							break;
					}
					break;
				case EDIT_STREET:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_COMPANY_STREET);
					break;
				case EDIT_ZIP:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_COMPANY_ZIP);
					break;
				case EDIT_CITY:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_COMPANY_CITY);
					break;
				case EDIT_STATE:
					if(HIWORD(wParam) == EN_UPDATE)
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_COMPANY_STATE);
					break;
				case EDIT_HOMEPAGE:
					if(HIWORD(wParam) == EN_UPDATE) {
						Edit_Changed(hDlg, LOWORD(wParam), USERINFO, SET_CONTACT_COMPANY_HOMEPAGE);
						EnableWindow(GetDlgItem(hDlg, BTN_GOTO), GetWindowTextLength((HWND)lParam) > 0);
					}
					break;
				case BTN_GOTO:
					Edit_OpenUrl(hDlg, EDIT_HOMEPAGE);
					break;
			}
			break;
		}

		case WM_DESTROY:
			Edit_Destroy(hDlg, EDIT_STREET);
			Edit_Destroy(hDlg, EDIT_ZIP);
			Edit_Destroy(hDlg, EDIT_CITY);
			Edit_Destroy(hDlg, EDIT_STATE);
			Edit_Destroy(hDlg, EDIT_HOMEPAGE);
			ComboBox_Destroy(hDlg, EDIT_COUNTRY);
			break;
	}
	return FALSE;
}
